#pragma once
/*--------------------------------------------------------------------------------
 * Adaptive Intelligence - Foundation Framework Class Library
 * Version 2.00
 * 
 * Kernel 32 API Class Library
 *      Provides static, managed acccess to API calls in the kernel32 library.
 *------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------
 * System Imports
 *------------------------------------------------------------------------------*/
#include "stdafx.h"

using namespace System;
using namespace System::ComponentModel;
using namespace System::ComponentModel::Design;
using namespace System::Security;
using namespace System::Security::Permissions;
using namespace System::Threading;
using namespace System::Runtime::InteropServices;
using namespace Adaptive::Foundation;
using namespace Adaptive::Win32;

namespace Adaptive
{
	namespace Win32
	{
		/// <summary>
		/// Provides static, managed acccess to API calls in the kernel32 library.
		/// </summary>
		public ref class InternalTimer sealed : public DisposableObjectBase
		{
		public:
			/*--------------------------------------------------------------------------------
			 * Public Event Definitions
			 *------------------------------------------------------------------------------*/
			#pragma region Public Event Definitions
			/// <summary>
			/// Occurs when the timer interval elapses.
			/// </summary>
			[System::Timers::TimersDescription("TimerIntervalElapsed"), Category("Behavior")]
			event EventHandler^ Elapsed;
			#pragma endregion

			/*--------------------------------------------------------------------------------
			 * Constructor / Dispose / Destructor Methods
			 *------------------------------------------------------------------------------*/
			#pragma region Constructor / Dispose / Destructor Methods
			/// <summary>
			/// Initializes a new instance of the class.
			/// </summary>
			/// <remarks>
			/// This is the default constructor.
			/// </remarks>
			InternalTimer();
			/// <summary>
			/// Initializes a new instance of the class to the specified interval.
			/// </summary>
			/// <param name="interval">
			/// The number of seconds to wait.
			/// </param>
			InternalTimer(float interval);
			/// <summary>
			/// Deallocates internally allocated objects.
			/// </summary>
			~InternalTimer();
			#pragma endregion

			/*--------------------------------------------------------------------------------
			 * Public Properties
			 *------------------------------------------------------------------------------*/
			#pragma region Public Properties
			/// <summary>
			/// Gets or sets a value indicating whether the <b>Timer</b> should raise the <b>Elapsed</b> event each time the 
			/// specified interval elapses or only after the first time it elapses.
			/// </summary>
			/// <value>
			/// <b>true</b> if the <see cref="Timer"/> should raise the <see cref="Elapsed"/> event each time the interval 
			/// elapses; <b>false</b> if it should raise the <see cref="Elapsed"/> event only once, after the first time the 
			/// interval elapses. The default is <b>true</b>.
			/// </value>
			property bool AutoReset { bool get(); void set(bool value); }
			/// <summary>
			/// Gets or sets the interval at which to raise the <see cref="Elapsed"/> event.
			/// </summary>
			/// <value>
			/// The time, in milliseconds, between raisings of the <see cref="Elapsed"/> event. The default is 0.5 seconds.
			/// </value>
			/// <exception cref="ArgumentException">The interval is less than or equal to zero. </exception>
			[RecommendedAsConfigurable(true), DefaultValue((float)0.5), Category("Behavior"), System::Timers::TimersDescription("TimerInterval")]
			property float Interval { float get(); void set(float value); }
			#pragma endregion 

			/*--------------------------------------------------------------------------------
			 * Public Methods / Functions
			 *------------------------------------------------------------------------------*/
			#pragma region Public Methods / Functions
			/// <summary>
			/// Clears the contents of the object instance without disposing of the instance.
			/// </summary>
			void Close();
			/// <summary>
			/// Starts the execution of the time-monitoring thread.
			/// </summary>
			void Start();
			/// <summary>
			/// Stops the execution of the time-monitoring thread.
			/// </summary>
			void Stop();
			#pragma endregion

		protected:
			/*--------------------------------------------------------------------------------
			 * Protected Methods / Event Methods
			 *------------------------------------------------------------------------------*/
			#pragma region Protected Methods / Event Methods
			/// <summary>
			/// Raises the <see cref="Elapsed"/> event.
			/// </summary>
			/// <param name="e"></param>
			void OnElapsed(EventArgs^ e);
			#pragma endregion

		private:
			/*--------------------------------------------------------------------------------
			 * Private Member Declarations
			 *------------------------------------------------------------------------------*/
			#pragma region Private Member Declarations
			/// <summary>
			/// Default interval value.
			/// </summary>
			static float DEFAULT_INTERVAL = 0.5f;
			/// <summary>
			/// Interval to wait, in seconds.
			/// </summary>
			float _interval;
			/// <summary>
			/// Number of ticks per secon on implementing machine.
			/// </summary>
			__int64 _ticksPerSecond;
			/// <summary>
			/// Auto-reset flag.
			/// </summary>
			bool _autoReset;
			/// <summary>
			/// Thread execution flag.
			/// </summary>
			bool _execThread;
			/// <summary>
			/// Thread instance.
			/// </summary>
			Thread^ _timeThread;

			CRITICAL_SECTION* _ct;
			HANDLE _threadEndEvent;
			#pragma endregion

			/// <summary>
			/// Executes the time-monitoring thread.
			/// </summary>
			void RunThread();
		};
	}
}
